﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using SyncList.UserInterface.Helpers;
using SyncList.Business.ValueObject;
using System.Collections;
using System.Collections.Specialized;

namespace SyncList.UserInterface
{
	/// <summary>
	/// Interaction logic for UCNavigationPath.xaml
	/// </summary>
	public partial class UCNavigationPath : UserControl, INotifyPropertyChanged
	{

        /// <summary>
        /// Liste des dossiers à afficher
        /// </summary>
        //private DirectoryContent[] _directories;



		public UCNavigationPath()
		{
			this.InitializeComponent();
		}


        //#region DependencyProperty Path
                
        //[System.ComponentModel.Category("OptimControl"), System.ComponentModel.Description("Propriété de dépendance Optim")]                
        //public string Path
        //{
        //    get { return (string)GetValue(PathProperty); }
        //    set { SetValue(PathProperty, value); }
        //}

        //// Using a DependencyProperty as the backing store for Path.  This enables animation, styling, binding, etc... (Snippet by ELR)
        //public static readonly DependencyProperty PathProperty = 
        //    DependencyProperty.Register("Path", typeof(string), typeof(UCNavigationPath), new PropertyMetadata("", PathChanged));

        ///// <summary>
        ///// La valeur de Path a été modifiée
        ///// </summary>
        ///// <param name="d"></param>
        ///// <param name="e"></param>
        //private static void PathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        //{
        //    UCNavigationPath source = (UCNavigationPath)d;
        //    string newValue = (string)e.NewValue;
            
        //    source.Update(newValue);

        //    // - Notifier la modification au niveau de la classe
        //    source.OnPropertyChanged("Path");
        //}
        
        //#endregion
        
        #region Méthodes


        ///// <summary>
        ///// Mettre à jour
        ///// </summary>
        ///// <param name="path"></param>
        //private void Update(string path)
        //{
        //    this.StackPanelPath.Children.Clear();
        //    string[] parts = path.Split('\\');

        //    StackPanelPath.Children.Add(GenereTriangle());

        //    foreach(string part in parts)
        //    {
        //        if (String.IsNullOrWhiteSpace(part)) continue;
        //        Button button = new Button();
        //        button.Content = part;
        //        button.Height = 30;
        //        button.Padding = new Thickness(8, 0, 8, 0);
        //        button.FontSize = 14;
        //        StackPanelPath.Children.Add(button);
        //        StackPanelPath.Children.Add(GenereTriangle());
        //    }
        //}


        /// <summary>
        /// Mettre à jour
        /// </summary>
        /// <param name="path"></param>
        private void Update()
        {
            this.StackPanelPath.Children.Clear();
            
            if(DirectoryParts != null)
            {

                StackPanelPath.Children.Add(GenereTriangle());

                foreach (DirectoryContent directory in DirectoryParts)
                {
                    Button button = new Button();
                    button.Content = directory.RelativePath;
                    button.Height = 30;
                    button.Padding = new Thickness(8, 0, 8, 0);
                    button.FontSize = 14;
                    button.Tag = directory;
                    button.Click += new RoutedEventHandler(button_Click);
                    StackPanelPath.Children.Add(button);
                    StackPanelPath.Children.Add(GenereTriangle());
                }
            }
        }



        /// <summary>
        /// Clic sur un bouton
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void button_Click(object sender, RoutedEventArgs e)
        {
            Button btn = (Button)sender;
            DirectoryContent directory = btn.Tag as DirectoryContent;
            if (directory != null)
                OnDirectorySelected(directory);
        }


        #region Event DirectorySelected

        public event EventHandler<DirectoryEventArgs> DirectorySelected;

        private void OnDirectorySelected(DirectoryContent directory)
        {
            if(DirectorySelected != null)
                DirectorySelected(this, new DirectoryEventArgs(directory));
        }


        #endregion


        /// <summary>
        /// Générer un triangle pointé vers la droite
        /// </summary>
        /// <returns></returns>
        private FrameworkElement GenereTriangle()
        {
            Rectangle rect = new Rectangle();
            rect.Width = 16;
            rect.Height = 16;
            rect.Fill = IconHelper.GetImageBrush("triangle.png");
            rect.StrokeThickness = 0;
            rect.Margin = new Thickness(4, 0, 4, 0);
            rect.VerticalAlignment = System.Windows.VerticalAlignment.Center;
            return (rect);
        }


        #endregion


        #region DependencyProperty DirectoryParts
                
        [System.ComponentModel.Category("OptimControl"), System.ComponentModel.Description("Propriété de dépendance Optim")]                
        public IEnumerable DirectoryParts
        {
            get { return (IEnumerable)GetValue(DirectoryPartsProperty); }
            set { SetValue(DirectoryPartsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DirectoryParts.  This enables animation, styling, binding, etc... (Snippet by ELR)
        public static readonly DependencyProperty DirectoryPartsProperty = 
            DependencyProperty.Register("DirectoryParts", typeof(IEnumerable), typeof(UCNavigationPath), new PropertyMetadata(null, DirectoryPartsChanged));

        /// <summary>
        /// La valeur de DirectoryParts a été modifiée
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        private static void DirectoryPartsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UCNavigationPath source = (UCNavigationPath)d;
            IEnumerable newValue = (IEnumerable)e.NewValue;
            IEnumerable oldValue = (IEnumerable)e.OldValue;
            
            INotifyCollectionChanged oldCollection = oldValue as INotifyCollectionChanged;
            INotifyCollectionChanged newCollection = newValue as INotifyCollectionChanged;
            
            // --- Libérer l'ancienne instance
            if (oldCollection != null)
            {
                oldCollection.CollectionChanged -= new System.Collections.Specialized.NotifyCollectionChangedEventHandler(source.DirectoryParts_CollectionChanged);

            }

            // --- S'abonner à la nouvelle instance
            if (newCollection != null)
            {           
                newCollection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(source.DirectoryParts_CollectionChanged);

                // - Les éléments actuellement dans la collection doivent être traités
                source.DirectoryParts_AddItems(newValue);
            }
            
            // - Notifier la modification au niveau de la classe
            source.OnPropertyChanged("DirectoryParts");
        }
        
        
        /// <summary>
        /// Lorsque le contenu de la collection est modifié, nous devons soit vider soi regénérer 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DirectoryParts_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {

                case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
                    DirectoryParts_AddItems(e.NewItems);                   
                    break;

                case System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
                    Update();
                    break;

                default:
                    throw new NotSupportedException("seuls NotifyCollectionChangedAction.Add et NotifyCollectionChangedAction.Reset sont supportés");

            }
        }
        
        /// <summary>
        /// Effectuer un traitement sur les nouveaux éléments en provenance de la collection 
        /// </summary>
        private void DirectoryParts_AddItems(IEnumerable source)
        {
            //foreach (object item in source)
            //{
            //  // TODO : Add your code here
            //}
                   
            Update();
        }
        
        #endregion
        	
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler  PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            if(PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion


        ///// <summary>
        ///// Liste des dossiers à afficher
        ///// </summary>
        //public DirectoryContent[] Directories
        //{
        //    get { return (_directories); }
        //    set
        //    {
        //        _directories = value;
        //        Update(_directories);
        //    }
        //}


    }
}